package report

import (
	"context"
	"git.mycaigou.com/gfyx/common/authorize"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/repository/user"
	"git.myscrm.cn/golang/stark/v4"
	"time"

	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/utils"

	//"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/utils/cache"
	"git.mycaigou.com/gfyx/common/cache"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/repository/report"
	pb "git.mycaigou.com/gfyx/micro-gfyx-user-service/proto/micro_gfyx_user_service_proto/micro-gfyx-user-service"
)

const (
	REPORT_URL_CACHE_KEY = "gfyx:user_service:report_url:"
)

type ReportService struct {
	reportShareRepo    report.ReportShareRepositoryIface
	commonUserDataRepo user.CommonUserDataRepoIface
}

func NewReportService(
	reportShareRepo report.ReportShareRepositoryIface,
	commonUserDataRepo user.CommonUserDataRepoIface,
) ReportServiceIface {
	return &ReportService{
		reportShareRepo:    reportShareRepo,
		commonUserDataRepo: commonUserDataRepo,
	}
}

// 生成分享链接
func (r *ReportService) GenerateUrl(ctx context.Context, reportShare *report.ReportShare) (*report.ReportShare, error) {

	reportShare.CreatedOn = time.Now()
	reportShare.CreatedBy = reportShare.SharerUserId
	reportShare.ReportStatus = "未领取"
	reportShare.ReportStatusCode = 4
	reportShare.IsReceived = 0
	_, _ = r.reportShareRepo.Insert(ctx, reportShare)

	redisClient, _ := cache.Redis()
	cacheKey := r.GenerateUrlCacheKey(ctx, reportShare.Uid, reportShare.ClueSource, reportShare.ClueSourceId)
	_, err := redisClient.RPush(ctx, cacheKey, "T")

	if err != nil {
		return reportShare, err
	}

	return reportShare, nil
}

func (r *ReportService) GenerateUrlCacheKey(ctx context.Context, code string, clueSource string, clueSourceId string) string {
	return REPORT_URL_CACHE_KEY + clueSource + ":" + code
}

// 领取链接
func (r *ReportService) ReceiveUrl(ctx context.Context, userUid string, code string) (bool, error) {
	// 首先取出这条记录
	getInfoCondition := make(map[string]interface{})
	getInfoCondition["uid"] = code
	reportShare, err := r.reportShareRepo.GetInfo(ctx, getInfoCondition)

	if err != nil {
		return false, err
	}

	// 防并发
	redisClient, _ := cache.Redis()
	cacheKey := r.GenerateUrlCacheKey(ctx, code, reportShare.ClueSource, reportShare.ClueSourceId)
	token, err := redisClient.LPop(ctx, cacheKey)
	if err != nil {
		return false, err
	}
	if token != "T" {
		return false, nil
	}

	// 更新
	updateData := make(map[string]interface{})
	updateData["recipient_uid"] = userUid
	updateData["modified_by"] = userUid
	updateData["report_status"] = "未处理"
	updateData["is_received"] = 1
	updateData["receive_on"] = time.Now()
	_, err = r.reportShareRepo.Update(ctx, updateData, getInfoCondition)
	if err != nil {
		return false, err
	}

	// 获取分享人手机号
	commonUserInfo, err := r.commonUserDataRepo.GetInfoByUid(ctx, userUid)
	if err != nil {
		return false, err
	}

	// 把租户code设置到上下文中，后面调用rpc方法时会用到
	ctx = context.WithValue(ctx, authorize.TENANT_CODE_KEY, reportShare.TenantCode)

	// 发送微信通知
	if err := r.reportShareRepo.SendShareReceiveMsg(ctx, reportShare.TenantCode, reportShare.ClueSourceTitle, reportShare.SharerUserTenantId, commonUserInfo.MobilePhone); err != nil {
		stark.Logger.Errorf(ctx, "发送微信消息失败: %s", err.Error())
	}

	return true, nil
}

// 获取报备列表
func (r *ReportService) ReportFromSharingList(ctx context.Context, condition map[string]interface{}, pageInfo *utils.PageInfo, orderBy string) (int64, []*report.ReportShare, error) {
	total, reports, err := r.reportShareRepo.GetList(ctx, condition, pageInfo, orderBy)
	if err != nil {
		return 0, nil, err
	}

	return total, reports, nil
}

// 获取报备详情
func (r *ReportService) ReportInfo(ctx context.Context, condition map[string]interface{}) (*report.ReportShare, error) {
	report, err := r.reportShareRepo.GetInfo(ctx, condition)

	if err != nil {
		return nil, err
	}

	return report, nil
}

// 更新状态
func (r *ReportService) UpdateReportShareStatus(ctx context.Context, userUid string, code string, reportShare *pb.ReportFromSharing) (bool, error) {
	getInfoCondition := make(map[string]interface{})
	getInfoCondition["uid"] = code

	updateData := make(map[string]interface{})
	updateData["modified_by"] = userUid
	if reportShare.ReportStatus != "" {
		updateData["report_status"] = reportShare.ReportStatus
	}
	if reportShare.ReportStatusCode != 0 {
		updateData["report_status_code"] = reportShare.ReportStatusCode
	}

	if reportShare.SubmitterName != "" {
		updateData["submitter_name"] = reportShare.SubmitterName
	}

	if reportShare.TenantReportId != "" {
		updateData["tenant_report_id"] = reportShare.TenantReportId
	}
	if reportShare.ClueSourceTitle != "" {
		updateData["clue_source_title"] = reportShare.ClueSourceTitle
	}
	if reportShare.CompanyName != "" {
		updateData["company_name"] = reportShare.CompanyName
	}
	if reportShare.CityCode != "" {
		updateData["city_code"] = reportShare.CityCode
	}
	if reportShare.ProvinceCode != "" {
		updateData["province_code"] = reportShare.ProvinceCode
	}

	_, err := r.reportShareRepo.Update(ctx, updateData, getInfoCondition)
	if err != nil {
		return false, err
	}

	return true, nil
}
